﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.ServiceProcess;
using System.Timers;
using System.Reflection;
using log4net;
using Koonsoft.Tool.SendMessage;

namespace Koonsoft.Tool.WatchService
{
    public class Program
    {
        private readonly static ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        static void Main(string[] args)
        {
            try
            {
                CheckConfig();

                log.Info(string.Format("守护服务的程序已启动"));
                log.Info(string.Format("定时扫描间隔设置为 {0} 秒", ConfigurationManager.AppSettings["WatchSpan"]));

                SendMessage.SendShortMessage.SendToSingleTarget("WCF服务", string.Format("{0} 守护ECSS服务的程序已启动", DateTime.Now.ToString("HH时mm分ss秒")));

                log.Info("发送程序启动的通知短信成功");

                Timer timer = new Timer(1000 * 10);
                timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

                timer.Interval = 1000 * Convert.ToInt32(ConfigurationManager.AppSettings["WatchSpan"]);
                timer.Enabled = true;

                Timer scanPortsTimer = new Timer();
                scanPortsTimer.Elapsed += new ElapsedEventHandler(OnScanPortEvent);

                scanPortsTimer.Interval = 1000 * Convert.ToInt32(ConfigurationManager.AppSettings["ScanPortSpan"]);
                scanPortsTimer.Enabled = true;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.ReadLine();
            }

        }

        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            string serviceName = ConfigurationManager.AppSettings["ServiceName"];

            //ServiceController service = new ServiceController(serviceName);

            foreach (string s in ConfigurationManager.AppSettings["ServiceNames"].Split(','))
            {
                try
                {
                    if (!String.IsNullOrEmpty(s))
                    {
                        ServiceController service = new ServiceController(s);

                        // 在指定时间内无法启动就视为服务器重启失败
                        int resettime = Convert.ToInt32(ConfigurationManager.AppSettings["ServiceResetTime"]);
                        TimeSpan timeout = TimeSpan.FromMilliseconds(1000 * resettime);

                        if (service.Status == ServiceControllerStatus.Stopped || service.Status == ServiceControllerStatus.Paused)
                        {
                            log.Warn(string.Format("发现服务【{0}】停止！", s));
                            SendMessage.SendShortMessage.SendToSingleTarget("服务守护", string.Format("{0} 发现服务【{1}】停止！", DateTime.Now.ToString("HH时mm分ss秒"), s));

                            service.Start();

                            service.WaitForStatus(ServiceControllerStatus.Running, timeout);

                            log.Info(string.Format("重启服务【{0}】成功", s));
                            SendMessage.SendShortMessage.SendToSingleTarget("服务守护", string.Format("{0} 重启服务【{1}】成功！", DateTime.Now.ToString("HH时mm分ss秒"), s));

                            ScanListenningPorts.ScanPorts();
                        }
                    }
                }
                catch
                {
                    log.Warn(string.Format("服务【{0}】无法启动", ConfigurationManager.AppSettings["ServiceName"]));
                    SendMessage.SendShortMessage.SendToSingleTarget("服务守护", string.Format("{0} 试图重启服务【{1}】失败！", DateTime.Now.ToString("hh时mm分ss秒"),s));
                }
            }
        }

        private static void OnScanPortEvent(object source, ElapsedEventArgs e)
        {
            try
            {
                ScanListenningPorts.ScanPorts();
                log.Info("扫描WCF端口，状态正常");
            }
            catch (Exception ex)
            {
                log.Error("定时扫描WCF端口出错", ex);
                SendMessage.SendShortMessage.SendToSingleTarget("定时扫描WCF端口", "某WCF端口已停止，请速检查");
            }

        }

        private static void CheckConfig()
        {
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["ServiceNames"]))
            {
                log.Warn("配置文件缺少ServiceNames节点", new Exception("请检查Config文件AppSettings项是否存在ServiceNames节点，并且该节点值不为空"));
            }

            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["WatchSpan"]))
            {
                log.Warn("配置文件缺少WatchSpan节点", new Exception("请检查Config文件AppSettings项是否存在WatchSpan节点，并且该节点值不为空"));
            }
        }

    }
}
